﻿using e_commerce.BLL.Data;
using e_commerce.BLL.Models;
using e_commerce.BLL.Services.Enterprise;
using System;
using System.Collections.Generic;
using System.Linq;

namespace e_commerce.BLL
{
    public class PermissionsService : IDisposable//提供权限访问，配置权限
    {
        private commerceDbContext _dbContext;
        private AccountService _aService;
        private RoleManager _rManager;
        private EmployeeService _eService;
        private static List<Menu> Menus { get; } = new List<Menu>()
        {
            new Menu {MenuId=1,MenuName="订单中心",Code="Order",ParentId=0,Url="",Icon="/Image/icon_order.png"},
            new Menu {MenuId=2,MenuName="评论中心",Code="Comment",ParentId=0,Url="" ,Icon="/Image/icon_comment.png"},
            new Menu {MenuId=3,MenuName="商品管理中心",Code="GoodsManager",ParentId=0,Url="",Icon="/Image/icon_thing.png" },
            new Menu {MenuId=4,MenuName="服务中心",Code="Server",ParentId=0,Url="",Icon="/Image/icon_service.png" },
            new Menu {MenuId=5,MenuName="全部订单",Code="Order.All",ParentId=1,Url="/Order/AllOrder" },
            new Menu {MenuId=6,MenuName="订单回收站",Code="Order.Recycle",ParentId=1,Url="/Order/OrderRecycle" },
            new Menu {MenuId=7,MenuName="全部评论",Code="Comment.All",ParentId=2,Url="/Comment/AllComment" },
            new Menu {MenuId=8,MenuName="全部商品",Code="GoodsManager.All",ParentId=3,Url="/Goods/AllGoods" },
            new Menu {MenuId=9,MenuName="已上架商品",Code="GoodsManager.OnShelves",ParentId=3,Url="/Goods/OnShelves" },
            new Menu {MenuId=10,MenuName="未上架商品",Code="GoodsManager.UnShelves",ParentId=3,Url="/Goods/UnShelves" },
            new Menu {MenuId=11,MenuName="退款管理",Code="Server.Refund",ParentId=4,Url="/Refund/Refund" },
            new Menu {MenuId=12,MenuName="仓库管理",Code="StoreManagement",ParentId=0,Url="", Icon="/Image/icon_staff.png"},
            new Menu {MenuId=13,MenuName="新增商品",Code="StoreManagement.CreateGoods",ParentId=12,Url="/Store/CreateGoods" },
            new Menu {MenuId=14,MenuName="已有商品",Code="StoreManagement.Goods",ParentId=12,Url="/Store/ExistGoods" },
            new Menu {MenuId=15,MenuName="已下架商品",Code="GoodsManager.OffShelves",ParentId=3,Url="/Goods/OffShelves" },
            new Menu {MenuId=16,MenuName="已处理订单",Code="Order.Deal",ParentId=1,Url="/Order/DealOrder" },
            new Menu {MenuId=17,MenuName="未处理订单",Code="Order.Untreated",ParentId=1,Url="/Order/UntreatedOrder" },
            new Menu {MenuId=18,MenuName="员工管理",Code="EmployeeManage",ParentId=0,Url="",Icon="/Image/icon_staff.png" },
            new Menu {MenuId=19,MenuName="全部员工",Code="EmployeeManage.AllEmployee",ParentId=18,Url="/Manage/All" },
            new Menu {MenuId=20,MenuName="新添员工",Code="EmployeeManage.AddEmployee",ParentId=18,Url="/Manage/Add" },
           /* new Menu {MenuId=21,MenuName="个人信息",Code="EmployeeManage.Personal",ParentId=18,Url="/Manage/Personal" },*/
        };

        public PermissionsService()
        {
            _dbContext = new commerceDbContext();
            _aService = new AccountService();
            _rManager = new RoleManager();
            _eService = new EmployeeService();
        }

        public IEnumerable<Permissions> GetUserPermissions(int userId)
        {
            User user = _aService.GetUserById(userId);
            var roles = user.Role.ToList();
            var roleIds = roles.Select(d => d.RoleId);

            List<Permissions> rolesPermissions = _dbContext.Permissions.Where(d => d.Role.Any(x => roleIds.Contains(x.RoleId))).ToList();

            IEnumerable<Permissions> privilege = user.Permissions;
            IEnumerable<Permissions> userPermissions = privilege.Union(rolesPermissions);
            return userPermissions;
        }
        public IEnumerable<Permissions> GetEmployeePermissions(int employeeId)
        {
            var employee = _dbContext.Employee.SingleOrDefault(e => e.Id == employeeId);
            if(employee == null)
            {
                throw new Exception("employee not found");
            }
            return GetUserPermissions(employee.UserId);
        }
        public IEnumerable<Menu> GetPermissionsMenu(int userId)
        {
            List<Permissions> userPermissions = GetUserPermissions(userId).ToList();
            var menus = Menus.Where(menu => userPermissions.Any(permission => permission.Code.StartsWith(menu.Code) || menu.Code.StartsWith(permission.Code))).ToList();
            return menus;
        }

        public IEnumerable<Role> GetEmployeeRoles(int employeeId)
        {
            var employee = _eService.GetEmployee(employeeId);
            return employee.User.Role;
        }
        public void ConfigPermission(int employeeId,int[] permissionIds)
        {
            var employee = _eService.GetEmployee(employeeId);
            var user = _dbContext.User.SingleOrDefault(u=>u.UserId == employee.UserId);
            var permissions = _dbContext.Permissions.ToList();
            List<Permissions> list = new List<Permissions>();
            foreach (var id in permissionIds)
            {
                var permission = permissions.SingleOrDefault(p => p.PermissionsId == id);
                if(permission != null)
                {
                    list.Add(permission);
                }
            }
            user.Permissions = list;
            SaveChange();
        }
        public IEnumerable<PermissionsTree> GetAllPermissons()
        {
            //生成权限树，递归
            var permissions = _dbContext.Permissions;
            List<PermissionsTree> pTree = new List<PermissionsTree>();
            foreach (var p in permissions)
            {
                if (p.Code.Split(Permission.Separator.ToCharArray()).Count() == 1)
                {
                    pTree.Add(new PermissionsTree() { id = p.PermissionsId, name = p.Name, code = p.Code });
                }
            };
            GetPermissionsTree(2, _dbContext.Permissions, pTree);
            return pTree;
        }
        /// <summary>
        /// 通过递归生成权限树
        /// </summary>
        /// <param name="rank">权限等级</param>
        /// <param name="list">全部权限</param>
        /// <param name="pTree">已生成的权限</param>
        private void GetPermissionsTree(int rank, IEnumerable<Permissions> list, IEnumerable<PermissionsTree> pTree)
        {
            var children = list.Where(p => p.Code.Split(Permission.Separator.ToCharArray()).Count() == rank).Select(l => new PermissionsTree()
            {
                id = l.PermissionsId,
                name = l.Name,
                code = l.Code,
            }).ToList();

            foreach (var tree in pTree) { tree.children = children.Where(p => p.code.StartsWith(tree.code)).ToList(); };
            foreach (var l in list) { if (l.Code.Split(Permission.Separator.ToCharArray()).Length == rank + 1) GetPermissionsTree(rank + 1, list, pTree); return; };  
        }
        public void Dispose()
        {
            _dbContext.Dispose();
        }

        public void SaveChange()
        {
            _dbContext.SaveChanges();
        }
    }
}
